import config from '@/common/config';
import permision from '@/common/permission';
import utils from '@/common/utils';
import math from '@/common/math';
// import { mapState } from 'vuex';
import {
  // extEncoder,
  TextDecoder
} from 'text-decoding'

const statusBarHeight = uni.getSystemInfoSync().statusBarHeight;

// 新增方法
const graceRichText = require('@/common/richText.js');

export default {
  data() {
    return {
      statusBarHeight: statusBarHeight,
      hasUnReadMessage: false,
      imagePrefix: config.imagePrefix,
      oriPriceVisible: false,
      pageScrollTop: 0,
    };
  },
  filters: {
    filterNull(value = '') {
      return value.replace('null', '');
    },
    // 时间格式化
    dateFormat(timestamp, fmt) {
      return utils.dateFormat(timestamp, fmt);
    },
    toInt(value) {
      return Number(value) || 0;
    },
    mobileFilter(value) {
      if (!value) return '';
      return value.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
    },
  },
  // 页面滚动执行方式
  // computed: {
  //   ...mapState({
  //     modalVisable: (state) => state.modalVisable,
  //     modalOpenStyles: (state) => state.modalOpenStyles,
  //   }),
  // },
  onPageScroll(e) {
    // if (!this.modalVisable)
    this.pageScrollTop = e.scrollTop;
  },
  methods: {
    ...math,
    disabledScroll() {
      return;
    },
    // setModalVisable(flag = false, offset = 44) {
    //   this.$store.commit('setModalVisable', { flag, offset, pageScrollTop: this.pageScrollTop });
    // },
    dateFormatFun: utils.dateFormat,
    formatDate(shijianchuo) {
      return utils.dateFormat(shijianchuo, 'YYYY-MM-DD hh:mm:ss');
    },
    formatNs(shijianchuo) {
      return utils.dateFormat(shijianchuo, 'DD-MM hh:mm')
    },
    formatY(shijianchuo) {
      return utils.dateFormat(shijianchuo, 'YYYY-MM-DD')
    },
    formatH(shijianchuo) {
      return utils.dateFormat(shijianchuo, 'hh:mm:ss')
    },
    formatD(shijianchuo) {
      return utils.dateFormat(shijianchuo, 'DD-MM hh:mm:ss')
    },
    checkPswString(str) {
      const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/g;
      if (!reg.test(str)) {
        return false;
      } else {
        return true;
      }
    },
    checkNameString(str) {
      // let reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{3,18}$/g;
      // let reg = /^[A-Za-z0-9]{3,18}$/g;
      let reg = /^[A-Za-z0-9\u4e00-\u9fa5\-_.?@]{5,80}$/g;
      if (!reg.test(str)) {
        return false
      } else {
        return true
      }
    },
    checkPhoneString(str) {
      let reg = /^[A-Za-z0-9\u4e00-\u9fa5\-_.?@]{6,}$/g;
      if (!reg.test(str)) {
        return false
      } else {
        return true
      }
    },
    checkEmailString(str) {
      let reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
      if (!reg.test(str)) {
        return false
      } else {
        return true
      }
    },
    checkNewMessage() {
      return this.apiUrl.checkNewMessage().then((res) => {
        if (res.data.code == 0) {
          if (res.data.data) this.hasUnReadMessage = true;
          else this.hasUnReadMessage = false;
        }
      });
    },
    checkLogin(showCancel = true, autoId=false,path=false) {
      const vm = this
      const memberInfo = this.$store.state.memberInfo || {};
      if (!memberInfo.id) {
        uni.showModal({
          title: '提示',
          content: '请先登录后再查看',
          confirmText: '确定',
          cancelText: '取消',
          showCancel,
          success: async (res) => {
            if(!vm.isObjectEmptyOrUndefined(vm.$store.state.memberInfo)){
              await vm.$store.dispatch('check_wx_login')
            }
            if(!vm.$store.state.openid) return
            uni.navigateTo({ url: path });

            // let url = '/pages/login/login';
            // if (autoId) {
            //   url = `${url}?autoId=${autoId}`;
            // }
            // if (res.confirm) {
            //   uni.setStorageSync('pagefromDetail', true);
            //   uni.navigateTo({ url });
            // } else if (res.cancel) {
            //   // console.log('用户点击取消');
            // }
          },
        });
        return false;
      }
      return true;
    },
    toPage(path, needLogin) {
      // if (needLogin && !this.checkLogin(true,false,path)) {
      //   return;
      // }
      uni.navigateTo({
        url: path,
      });
    },
    // 滚动到顶部
    backToTop(duration = 300) {
      // 控制滚动
      uni.pageScrollTo({
        scrollTop: 0,
        duration,
      });
    },
    clipBoard(str) {
      if (str && typeof str !== "string") str = str.toString();
      // #ifdef H5
      this.copyTextToClipboard(str);
      // #endif
      // #ifndef H5
      uni.setClipboardData({
        data: str,
        success: function () {
          uni.showToast({
            title: '复制成功',
            icon: 'none',
            mask: false,
            duration: 1500,
          });
        },
      });
      // #endif
    },
    copyTextToClipboard(text) {
      var textArea = document.createElement('textarea');
      textArea.style.position = 'fixed';
      textArea.style.top = 0;
      textArea.style.left = 0;
      textArea.style.width = '2em';
      textArea.style.height = '2em';
      textArea.style.padding = 0;
      textArea.style.border = 'none';
      textArea.style.outline = 'none';
      textArea.style.boxShadow = 'none';
      textArea.style.background = 'transparent';
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      try {
        var msg = document.execCommand('copy') ?'复制成功' : '复制失败';
        console.log('复制内容 ' + msg);
        uni.showToast({
          title: '复制成功',
          icon: 'none',
          mask: false,
          duration: 1500
        });
      } catch (err) {
        console.log('不能使用这种方法复制内容');
      }
      document.body.removeChild(textArea);
    },
    goBack() {
    	// #ifdef H5
    	// uni-app里面使用uni.navigateBack时，刷新页面会造成无法返回上一级页面
    	const pages = getCurrentPages()
    	if (pages.length > 1) {
    		uni.navigateBack(1)
    		return;
    	}
    	//使用vue-router返回上一级
    	let a = this.$router.go(-1)
    	if (a == undefined) {
    		//重新定向跳转页面
    		uni.reLaunch({
    			url: '/pages/index/index'
    		})
    	}
    	return;
    	// #endif
    	uni.navigateBack()
    },
    async checkPermission() {
      let status = permision.isIOS
        ? await permision.requestIOS('camera')
        : await permision.requestAndroid('android.permission.CAMERA');

      if (status === null || status === 1) {
        status = 1;
      } else {
        uni.showModal({
          content: '您未开启相机权限，请在设置中为广州商科打开相机权限',
          confirmText: '设置',
          success: function (res) {
            if (res.confirm) {
              permision.gotoAppSetting();
            }
          },
        });
      }
      return status;
    },
    sleep(time = 100) {
      return new Promise((resolve) => {
        const timer = setTimeout(() => {
          clearTimeout(timer);
          resolve();
        }, time);
      });
    },
    shareMiniProgram(options = {}) {
      const o = {
        provider: 'weixin',
        scene: options.scene || 'WXSceneSession',
        type: 5,
        title: options.title || '广州商科',
        imageUrl: options.imageUrl || config.defaultMpShareIcon,
        miniProgram: {
          id: config.wxMpOriginalId,
          path: options.path || 'pages/index/index',
          type: 2,
          webUrl: '',
        },
        success: (ret) => {
          // console.log(JSON.stringify(ret));
          if (typeof options.success == 'function') options.success(ret);
        },
      };

      uni.share(o);
    },
    // eslint-disable-next-line no-unused-vars
    showMessage(options) {
      return new Promise((resolve) => {
        options.icon = options.icon || 'none';
        options.duration = options.duration || 3000;
        uni.showToast(options);
        setTimeout(() => resolve(), options.duration);
      });
    },
    toRule(title, type) {
      const that = this;
      that.apiUrl
        .getRegisterAgreement({
          data: {
            type: type,
          },
        })
        .then((res) => {
          if (res.data.code == 0) {
            uni.setStorageSync('swiperContent', res.data.data.content);
            this.toPage('/pages/index/webPage/webPage?richText=true&title=' + title);
          } else if (res.data.message) {
            this.showMessage({ title: res.data.message });
          }
        });
    },
    // 登录跳转
    goLogin() {
      uni.navigateTo({
        url: '/pages/login/login',
      });
    },
    // 页面跳转
    navPage(path) {
      uni.navigateTo({
        url: path
      })
    },
    switchPage(path) {
      uni.switchTab({
        url: path
      })
    },
    redirectToPage(path) {
      uni.redirectTo({
        url: path
      })
    },
    // 自定义tabbar跳转
    toSwithIndex(fromTabbar){
      // #ifndef APP-PLUS
      uni.redirectTo({
        url:fromTabbar
      })
      // #endif
      // #ifdef APP-PLUS
      uni.switchTab({
        url:fromTabbar
      })
      // #endif
    },
    moveHandle() {
      return;
    },

    // 新增方法start
    // 给数组添加id
    setArrListId(arr){
      // 生成唯一key
      // let api_uuid = parseInt(new Date().getTime()) + Math.random().toString(36).substr(2, 15);

      if(arr&&arr.length>0){
        var newArr=arr.map(item=>({
          id:item.id ? item.id : (parseInt(new Date().getTime()) + Math.random().toString(36).substr(2, 15)),
          ...item,
        }))
        // console.log("newArr",newArr)
        return newArr
      }
      return arr
    },
    // 最长六位小数
    toFixedNum(num, places=6){
      if (typeof num == 'string'){
        num = parseFloat(num);
      }
      if(!num) return;
      num = num.toFixed(places).replace(/[.]?0+$/g,"");
      return num
    },
    // 获取url参数
    GetQueryString(name){
      var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
      var r = window.location.search.substr(1).match(reg);
      // var r = '?redEnvelopeCode=123'
      r = r.substr(1).match(reg);
      if(r!=null)return unescape(r[2]); return null;
    },
    // 过滤复文本特殊符号
    filterSpecialSymbol(str) {
      // str = str.replace(/\<img/gi, '<img style="max-width:100%;height:auto" ');
      // base64转utf-8
      if(str){
        str = this.base64ToUtf8(str);
        // #ifndef MP-WEIXIN
        str = graceRichText.format(str);
        // rich-text处理换行符
        if(str.trim() != ''){
          str = str.split('\n').reduce((total, cur) => total += `<p>${cur}</p>`)
        }
        // #endif
      }
      return str;
    },
    // 判断是不是base64
    isBase64(str) {
      const base64Regex = /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/;
      const urlSafeBase64Regex = /^(?:[A-Za-z0-9_\-]{4})*(?:[A-Za-z0-9_\-]{2}==|[A-Za-z0-9_\-]{3}=)?$/;
      return base64Regex.test(str) || urlSafeBase64Regex.test(str);
    },
    // 封装base64方法
    Base64() {
        // private property
        let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

        // public method for encoding
        this.encode = function (input) {
            let output = "";
            let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            let i = 0;
            input = _utf8_encode(input);
            while (i < input.length) {
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);
                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;
                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }
                output = output +
                _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
            }
            return output;
        }

        // public method for decoding
        this.decode = function (input) {
            let output = "";
            let chr1, chr2, chr3;
            let enc1, enc2, enc3, enc4;
            let i = 0;
            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
            while (i < input.length) {
                enc1 = _keyStr.indexOf(input.charAt(i++));
                enc2 = _keyStr.indexOf(input.charAt(i++));
                enc3 = _keyStr.indexOf(input.charAt(i++));
                enc4 = _keyStr.indexOf(input.charAt(i++));
                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;
                output = output + String.fromCharCode(chr1);
                if (enc3 != 64) {
                    output = output + String.fromCharCode(chr2);
                }
                if (enc4 != 64) {
                    output = output + String.fromCharCode(chr3);
                }
            }
            output = _utf8_decode(output);
            return output;
        }

        // private method for UTF-8 encoding
        let _utf8_encode = function (string) {
            string = string.replace(/\r\n/g,"\n");
            let utftext = "";
            for (let n = 0; n < string.length; n++) {
                let c = string.charCodeAt(n);
                if (c < 128) {
                    utftext += String.fromCharCode(c);
                } else if((c > 127) && (c < 2048)) {
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
                } else {
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
                }

            }
            return utftext;
        }

        // private method for UTF-8 decoding
        let _utf8_decode = function (utftext) {
            let string = "";
            let i = 0;
            let c = 0, c1 = 0, c2 = 0, c3 = 0;
            while ( i < utftext.length ) {
                c = utftext.charCodeAt(i);
                if (c < 128) {
                    string += String.fromCharCode(c);
                    i++;
                } else if((c > 191) && (c < 224)) {
                    c2 = utftext.charCodeAt(i+1);
                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                    i += 2;
                } else {
                    c2 = utftext.charCodeAt(i+1);
                    c3 = utftext.charCodeAt(i+2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                    i += 3;
                }
            }
            return string;
        }
    },
    // base64转utf-8
    base64ToUtf8(base64String) {
      let utf8String = base64String;
      if(utf8String&&this.isBase64(base64String)){
        // #ifndef MP-WEIXIN
        utf8String = atob(base64String);
        // #endif
        // #ifdef MP-WEIXIN
        // 由于小程序环境不支持 atob 函数，你可以使用微信小程序提供的 wx.base64ToArrayBuffer 方法来替代解码Base64字符串的需求。
        // 条件判断是否在小程序环境中
        if (typeof atob !== 'function') {
          let atob = async (base64String) => {
            // 使用 wx.base64ToArrayBuffer 等小程序 API 实现解码逻辑
            // const arrayBuffer = wx.base64ToArrayBuffer(base64);
            // 使用wx.base64ToArrayBuffer将Base64字符串转换为ArrayBuffer
            const arrayBuffer = await uni.base64ToArrayBuffer(base64String);

            // 方法1：使用TextDecoder
            const decoder = new TextDecoder('utf-8');
            utf8String = decoder.decode(arrayBuffer);
            return utf8String
          };
          utf8String = atob(base64String);
        }else {
          // utf8String = atob(base64String);
          // 新封装方法解释base64
          let base = new this.Base64();
          utf8String = base.decode(base64String);
        }
        // #endif
      }
      return utf8String;
    },
    // 对象转数组
    objTrantsArr(obj){
      let settingObj=obj;
      let settingArr = Object.keys(settingObj).map(key => {
        //console.log(key); //为每个键名
        // console.log(settingObj);
        return settingObj[key];  //把每个对象返回出去生成一个新的数组中相当于0:{id:1}
      });
      return settingArr;
    },
    add0(m) {
      return m < 10 ? '0' + m : m
    },
    isInteger(obj) {
      return typeof obj === 'number' && obj % 1 === 0
    },
    multiply(n1 = 0, n2 = 0) {
      var s1 = n1.toString()
      var s2 = n2.toString()
      var l1 = (s1.split('.')[1] || '').length
      var l2 = (s2.split('.')[1] || '').length
      var r1 = Number(s1.replace('.', ''))
      var r2 = Number(s2.replace('.', ''))
      return r1 * r2 / Math.pow(10, l1 + l2)
    },
    divide(n1 = 0, n2 = 0) {
      var s1 = n1.toString()
      var s2 = n2.toString()
      var l1 = (s1.split('.')[1] || '').length
      var l2 = (s2.split('.')[1] || '').length
      var r1 = Number(s1.replace('.', ''))
      var r2 = Number(s2.replace('.', ''))
      return this.multiply((r1 / r2), Math.pow(10, l2 - l1))
    },
    add(n1 = 0, n2 = 0) {
      var s1 = n1.toString()
      var s2 = n2.toString()
      var l1 = (s1.split('.')[1] || '').length
      var l2 = (s2.split('.')[1] || '').length
      var c = Math.abs(l1 - l2)
      var m = Math.pow(10, Math.max(l1, l2))

      var r1 = 0
      var r2 = 0
      if (c > 0) {
        var cm = Math.pow(10, c)
        if (l1 > l2) {
          r1 = Number(s1.replace('.', ''))
          r2 = Number(s2.replace('.', '')) * cm
        } else {
          r1 = Number(s1.replace('.', '')) * cm
          r2 = Number(s2.replace('.', ''))
        }
      } else {
        r1 = Number(s1.replace('.', ''))
        r2 = Number(s2.replace('.', ''))
      }
      return (r1 + r2) / m
    },
    subtract(n1 = 0, n2 = 0) {
      var l1 = (n1.toString().split('.')[1] || '').length
      var l2 = (n2.toString().split('.')[1] || '').length
      var m = Math.pow(10, Math.max(l1, l2))
      var n = (l1 >= l2) ? l1 : l2
      return Number(((n1 * m - n2 * m) / m).toFixed(n))
    },
    percentTwo(value, fmt) {
      return `${((value ||0) *100).toFixed(fmt ||2)}%`;
    },

    percentNum(value, fmt) {
      return `${((value ||0) *100)}`;
    },
    percentT(value, fmt) {
      return `${((value ||0) *100).toFixed(fmt ||3)}`;
    },
    // 是否是手机
    isMobile(){
      let flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
      // localStorage.setItem('isiphone',flag)
      localStorage.setItem('ismobile',flag?1:0);
      let goUrl = flag ? 1 : 0;
      return goUrl;
    },
    //判断两对象是否相等
    equalsObj(obj1, obj2) {
      // 首先判断是否是引用类型
      let f1 = obj1 instanceof Object;
      let f2 = obj2 instanceof Object;
      // 如果有一个不是引用数据类型，那就进行直接判断。（内存地址不同）
      if(!f1 || !f2){
        return obj1 === obj2
      }
      // 若全是引用类型的，那就先看一下属性值的长度是否相等，若不相等，就直接false啦。
      if(Object.keys(obj1).length !== Object.keys(obj2).length){
        return false
      }
      /**
       * 若属性值的长度相等，就接着遍历里边的每一个属性，还是先看里边的属性是哪一个类型，
       * 如果全是引用类型，那就接着对里边的属性调用equals递归函数。
       * 如果不全是引用类型，那就比较这两个值是否相等，若不相等就直接false啦。
       */
      for(let p in obj1){
        let a= obj1[p] instanceof Object;
        let b= obj2[p] instanceof Object;
        if(a && b){
          this.equalsObj(obj1[p],obj2[p])
        }else if(obj1[p]!=obj2[p]){
          return false;
        }
      }
      return true;
    },
    // 防抖函数
    debounceMin(fn, delay) {
      let timer;
      return function () {
        let context = this;
        let args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
          fn.apply(context, args);
        }, delay);
      };
    },
    // 节流
    throttleNew(fn, delay) {
      let ctx;
      let args;
      // 记录上次触发事件
      let previous = Date.now();

      let later = function () {
        fn.apply(ctx, args);
      };

      return function () {
        ctx = this;
        args = arguments;
        let now = Date.now();
        // 本次事件触发与上一次的时间比较
        let diff = now - previous - delay;

        // 如果隔间时间超过设定时间，即再次设置事件触发的定时器
        if (diff >= 0) {
          // 更新最近事件触发的时间
          previous = now;
          setTimeout(later, delay);
        }
      };
    },
    // 打开新窗口
    openlink(link){
      // #ifdef APP-PLUS
      plus.runtime.openURL(link);
      // #endif

      // #ifdef H5
      window.open(link,'_bank')
      // #endif
    },
    // 是否ios浏览器
    isIosSafari() {
      const ua = navigator.userAgent.toLowerCase();
      if (
        ua.indexOf('applewebkit') > -1 &&
        ua.indexOf('mobile') > -1 &&
        ua.indexOf('safari') > -1 &&
        !(ua.indexOf('android') > -1) &&
        !(ua.indexOf('linux') > -1) &&
        !(ua.indexOf('crios') > -1) &&
        !(ua.indexOf('chrome') > -1) &&
        !(ua.indexOf('browser') > -1) &&
        !(ua.indexOf('ios') > -1)
      ) {
        return true;
      }
      return false;
    },
    // 不为null、null、''
    isNotNull(val){
      if(val != null && val != undefined && val != ''){
        return true
      }
      return false
    },
    // 新增方法 end
    // 拨打电话弹框
    service(phone) {
      if(phone) phone = phone.toString()
      uni.showModal({
        title: '提示',
        content: '需要客服，请拨打电话' + phone,
        confirmText: '确定',
        cancelText: '取消',
        success: function(res) {
          if (res.confirm) {
            uni.makePhoneCall({
              phoneNumber: phone
            })
            // console.log('用户点击确定');
          } else if (res.cancel) {
            // console.log('用户点击取消');
          }
        }
      });
    },
    // 获取字符串空格前字符串
    getStringBeforeSpace(str) {
      const match = str.match(/^\S+/);
      return match ? match[0] : '';
    },
    // 检查对象多层嵌套中某个属性是否有值
    hasNestedProperty(obj, propPath) {
      const parts = propPath.split('.');
      let current = obj;

      for (let i = 0; i < parts.length; i++) {
        if (!current || current[parts[i]] === undefined || current[parts[i]] === null) {
          return false;
        }
        current = current[parts[i]];
      }

      return true;
    },
    // 对象不为空
    isObjectEmptyOrUndefined(obj) {
      return obj === undefined || obj === null || Object.keys(obj).length === 0;
    },
    // 手机号中间显示星号
    maskPhoneNumber(phoneNumber) {
      return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
    },
    // 手机号校验
    isValidPhoneNumber(phoneNumber) {
      // return /^1[0-9]{10}$/.test(phoneNumber);
      // 正则表达式：匹配11位数字（普通手机号码）
      const mobileRegex = /^[0-9]{11}$/;
      // 正则表达式：匹配带区号的座机号码，例如 "021-12345678" 或 "010-98765432"
      const landlineRegex = /^(0\d{2,3})-(\d{7,8})$/;
      // return mobileRegex.test(phoneNumber) || landlineRegex.test(phoneNumber);
      if (mobileRegex.test(phoneNumber)) {
        return mobileRegex.test(phoneNumber);
      } else if (landlineRegex.test(phoneNumber)) {
        return landlineRegex.test(phoneNumber);
      } else {
        return false;
      }
    },
    // 判断是否支持getFileSystemManager API
    isGetFileSystemManagerSupported() {
      // 通过uni的getSystemInfo或getSystemInfoSync方法获取平台信息
      const systemInfo = uni.getSystemInfoSync();
      // 通过平台信息判断是否为小程序环境
      if (systemInfo.environment === 'WEB') {
        // 在非小程序环境下，比如WEB环境，直接返回false
        return false;
      } else {
        // 在小程序环境下，根据平台类型判断是否支持getFileSystemManager
        const platform = systemInfo.platform;
        // 微信小程序在1.9.90版本之后支持getFileSystemManager
        if (platform === 'mp-weixin') {
          const version = systemInfo.SDKVersion;
          return parseInt(version.split('.').join('')) >= 1990;
        } else {
          // 其他小程序平台暂不做区分，统一认为支持
          return true;
        }
      }
    },
    /**
     * H5压缩 二分查找算法来找到一个合适的图像质量系数，使得压缩后的图片文件大小接近于目标大小
     * @param {Object} imgSrc 图片url
     * @param {Object} callback 回调设置返回值
     * */
    compressH5(fileItem, targetSizeKB, initialQuality = 1.0) {
    	const maxQuality = 1.0;
    	const minQuality = 0.0;
    	const tolerance = 0.01; // 根据需要调整公差
    	return new Promise((resolve, reject) => {
    		const binarySearch = (min, max) => {
    			 const midQuality = (min + max) / 2;

    			 const reader = new FileReader();
    			 reader.readAsDataURL(fileItem);
    			 reader.onload = function () {
    				 const img = new Image();
    				 img.src = this.result;
    				 img.onload = function () {
    					 const canvas = document.createElement('canvas');
    					 const ctx = canvas.getContext('2d');

    					 canvas.width = img.width;
    					 canvas.height = img.height;

    					 ctx.clearRect(0, 0, canvas.width, canvas.height);
    					 ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

    					 // 使用异步的 toBlob 方法
    					 canvas.toBlob(async (blob) => {
    						 const fileSizeKB = blob.size / 1024;

    						 if (Math.abs(fileSizeKB - targetSizeKB) < tolerance || max - min < tolerance) {
    							 // 当前质量足够接近目标大小，使用当前质量解析
    							 resolve(URL.createObjectURL(blob));
    						 } else if (fileSizeKB > targetSizeKB) {
    							 // 如果文件大小太大，降低质量，继续二分查找
    							 binarySearch(min, midQuality);
    						 } else {
    							 // 如果文件大小太小，增加质量，继续二分查找
    							 binarySearch(midQuality, max);
    						 }
    					 }, 'image/jpeg', midQuality);
    				 };
    			 };
    			 reader.onerror = function (error) {
    				 reject(error);
    			 };
    		};

    		// 开始二分查找
    		binarySearch(minQuality, maxQuality);
    	});
    },
    // 微信小程序图片缩放功能实现及闭坑
    previewImage(imageUrl) {
      console.log(imageUrl);
      uni.showLoading({
        title: '加载中...',
      })
      uni.downloadFile({
        url: imageUrl,
        success: (res) => {
          if (res.statusCode === 200) {
            const tempFilePath = res.tempFilePath;
            uni.previewImage({
              current: tempFilePath, // 当前显示图片的临时文件路径
              urls: [tempFilePath], // 需要预览的图片临时文件路径列表
              success: () => {
                console.log('Preview image success');
                uni.hideLoading()
              },
              fail: (err) => {
                console.error('Preview image failed:', err);
                uni.hideLoading()
                uni.showToast({
                  title: '图片加载失败，请检查图片路径',
                  icon: 'none',
                  duration: 2000
                });
              }
            });
          } else {
            console.error('Download file failed:', res);
            uni.hideLoading()
            uni.showToast({
              title: '图片下载失败，请检查网络连接',
              icon: 'none',
              duration: 2000
            });
          }
        },
        fail: (err) => {
          console.error('Download file failed:', err);
          uni.hideLoading()
          uni.showToast({
            title: '图片下载失败，请检查网络连接',
            icon: 'none',
            duration: 2000
          });
        }
      });
    },
    // js正则判断是否包含中文
    containsChinese(regex) {
      return /[\u4e00-\u9fa5]/.test(regex);
    },
    is(val, type) {
      return toString.call(val) === `[object ${type}]`;
    },
    //判断是否为undefined或者null
    isDef(val) {
      return typeof val !== 'undefined' && typeof val !== 'null';
    },
    isUnDef(val) {
      return !this.isDef(val);
    },
    //判断是否为字符串
    isString(val) {
      return this.is(val, 'String');
    },
    //判断是否为空字符串
    emptyString(val) {
      if (!this.isString(val) || this.isEmptyNew(val)) {
        return false;
      }
      let judgeFn = new RegExp(/\s+/g);
      return judgeFn.test(val);
    },
    //判断是否为对象
    isObjectNew(val) {
      return val !== null && val !== undefined && this.is(val, 'Object');
    },
    //判断是否为数组
    isArrayNew(val) {
      return val && Array.isArray(val);
    },
    //判断是否为空对象
    isEmptyNew(val) {
      if(this.isUnDef(val)){
        return true;
      }
      if (this.isArrayNew(val) || this.isString(val)) {
        return val.length === 0;
      }
      if (val instanceof Map || val instanceof Set) {
        return val.size === 0;
      }
      if (this.isObjectNew(val)) {
        return Object.keys(val).length === 0;
      }
      return false;
    },

  },
};
